<template>
  <!-- http数据导入 -->
  <a-form :form="form" :label-col="{ span: 3 }" class="form-section">
    <!-- 数据类型 -->
    <a-form-item
      label="数据类型"
      :label-col="{ span: 3 }"
      :label-align="'left'"
    >
      <a-radio-group v-model="dataType">
        <a-radio-button
          v-for="element in httpButtonImg"
          :key="element['name']"
          class="select-http-type"
          :value="element['name']"
        >
          <img
            :src="element.logo"
            :alt="element['name']"
            style="height: 50px; width: 78px;"
          />
        </a-radio-button>
      </a-radio-group>
    </a-form-item>
    <!-- 选择分类 -->
    <a-form-item
      label="选择文件夹"
      :label-col="{ span: 3 }"
      :label-align="'left'"
      class="form-item-content-width-285"
    >
      <a-select
        v-decorator="[
          'categoryId',
          {
            rules: [{ required: true, message: '请选择文件夹!' }],
            validateTrigger: ['blur', 'change'],
            initialValue: selectedCategoryId,
          },
        ]"
        placeholder="请选择"
        class="select-box"
        size="small"
        style="width: 316px;"
        @change="selectedCategoryIdChanged"
      >
        <a-select-option
          v-for="category in categorySelectOptions"
          :key="category.categoryId"
          :value="category.categoryId"
          >{{ category.categoryName }}
        </a-select-option>
      </a-select>
    </a-form-item>
    <!-- 数据集名称 -->
    <a-form-item
      label="数据集名称"
      :label-col="{ span: 3 }"
      :label-align="'left'"
      class="form-item-content-width-320"
    >
      <a-input
        v-decorator="[
          'datasetName',
          {
            rules: [
              { required: true, message: '请输入数据集名称!' },
              { validator: validateDatasetName },
            ],
            validateTrigger: ['blur', 'change'],
          },
        ]"
        class="name-input"
        :clearable="true"
        :max-length="50"
        placeholder="请输入数据集名称"
        size="small"
        style="width: 316px;"
        @change="changeDatasetName"
      >
        <a-icon
          v-show="datasetName.length > 0"
          slot="suffix"
          type="close-circle"
          style="cursor: pointer;"
          @mousedown="clearDatasetName"
        />
      </a-input>
    </a-form-item>
    <!-- JSON样式 -->
    <a-form-item
      label="JSON样式"
      :label-col="{ span: 3 }"
      :label-align="'left'"
      class="json-data"
    >
      <code-mirror-editor
        v-decorator="[
          'jsonData',
          {
            rules: [
              { required: true, message: '请输入或者导入JSON!' },
              { validator: validateJsonData },
            ],
            validateTrigger: ['blur', 'change'],
            initialValue: '',
            validateFirst: true,
          },
        ]"
        class="code-mirror"
        mode="application/json"
        from="httpImport"
        height="248"
      ></code-mirror-editor>
    </a-form-item>
    <!-- 上传文件 清空，执行 -->
    <a-form-item
      label=" "
      :label-col="{ span: 3 }"
      :label-align="'left'"
      :colon="false"
      class="upload-file"
    >
      <div class="import-file-box">
        <div class="file-upload-button">
          <a-upload
            v-decorator="['file']"
            accept=".json,.txt,text/plain"
            :file-list="fileList"
            class="csv-upload"
            :custom-request="() => {}"
            @change="handleUpload"
          >
            <a-tooltip placement="top">
              <template slot="title">
                点击上传
              </template>
              <a-button style="height: 24px; width: 78px;">
                <a-icon-font type="iconshujuguanli-daorushuju" />
                <span class="description">上传</span>
              </a-button>
            </a-tooltip>
          </a-upload>
          <span class="json-button-annotation">支持txt/json文件读取</span>
        </div>
        <div class="json-edit-buttons">
          <a-button
            size="small"
            style="height: 24px; width: 49px;"
            @click="clearInputText"
            >清空</a-button
          >
          <a-button
            type="primary"
            size="small"
            style="height: 24px; width: 49px;"
            @click="importHttp"
          >
            执行
          </a-button>
        </div>
      </div>
    </a-form-item>
  </a-form>
</template>

<script lang="ts">
/**
 * modal of http data (http数据导入)
 * @author Jinhui Hou
 */
import { Component, Prop } from 'vue-property-decorator'
import UploadDataMixin from '@/components/data/basic-information/upload-data-mixin'
import CodeMirrorEditor from '@/components/studio/data/popup/CodeMirrorEditor.vue'
import DataUploadStore from '@/store/modules/data-upload'
import DataStore from '@/store/modules/data'
import { HttpCreateTable, JsonValidate } from '@/api/data-import'
import { cloneDeep, isObject } from 'lodash'
import UserGuideStore from '@/store/modules/user-guide'

@Component({
  components: {
    CodeMirrorEditor,
  },
})
export default class HttpDataForm extends UploadDataMixin {
  @Prop({ type: Array, default: () => [] }) dataImages!: any[]
  public form: any //  http form表单
  public dataType: string = 'json' // 数据类型
  public datasetName: string = '' // 数据集名称
  private lastResponse: any

  // 获取 http 图片
  public get httpButtonImg() {
    const result: any[] = []
    this.dataImages.forEach((element: any) => {
      if (element.type === 'http') {
        result.push(element)
      }
    })
    return result
  }
  // 预览数据
  public get httpDatasetData() {
    return DataUploadStore.httpDatasetData
  }

  public beforeMount() {
    this.form = this.$form.createForm(this, { name: 'http_form' })
  }

  /**
   * 修改数据类型
   * @param value
   */
  public dataTypeChanged(value: string) {
    this.dataType = value
  }

  /**
   * 修改数据集名称
   * @param $event
   */
  public changeDatasetName($event: any) {
    this.datasetName = $event.target.value
  }

  /**
   * 验证数据集名称
   * todo 这里需要远程检测数据集是否已经存在
   */
  public validateDatasetName(rule: any, value: string, callback: Function) {
    if (value.includes(' ')) {
      callback('数据表名不允许含有空格!')
    }
    callback()
  }

  /**
   * 清除数据集名
   */
  public clearDatasetName() {
    this.form.setFieldsValue({ datasetName: '' })
    this.datasetName = ''
  }

  /**
   * 验证json数据
   */
  public validateJsonData(rule: Object, value: string, callback: Function) {
    if ([null, undefined, ''].includes(value)) {
      callback(new Error('数据不能为空'))
    }
    try {
      const valueParse = JSON.parse(value)
      if (valueParse) {
        if (isObject(valueParse) && Object.keys(valueParse).length === 0) {
          callback(new Error('请确保JSON数据存在有效字段'))
        } else {
          JsonValidate({
            data: value,
          })
            .then((response: any) => {
              if (response.data.code === 100) {
                callback()
                this.lastResponse = response.data.result
              } else {
                callback(new Error(response.data.message))
              }
            })
            .catch((error: Error) => {
              callback(error)
            })
        }
      }
    } catch (error) {
      callback(new Error(error))
    }
    callback()
  }

  /**
   * 校验文件类型和文件大小
   */
  public beforeUpload(file: any) {
    const isJsonOrTxt =
      file.type === 'application/json' || file.type === 'text/plain'
    if (!isJsonOrTxt) {
      this.$message.error('请上传 JSON 或者 TXT 文件')
    }
    const isLt100M = file.size / 1024 / 1024 < 100
    if (!isLt100M) {
      this.$message.error('超过文件大小限制（100M）!')
    }
    return isJsonOrTxt && isLt100M
  }

  /**
   * 只能上传一个文件，重复上传会覆盖
   */
  public async handleUpload(info: any) {
    if (!this.beforeUpload(info.file)) {
      return
    }
    this.fileList = [...info.fileList].slice(-1)
    if (info.fileList.length === 0) {
      DataUploadStore.setHttpDatasetData(null)
    } else {
      const reader = new FileReader()
      reader.readAsText(this.fileList[0].originFileObj)
      /* eslint-disable */
      reader.onload = () => {
        if (reader.result) {
          this.validateJsonData(
            {},
            reader.result as string,
            (error: Error | undefined) => {
              if (error) {
                this.form.setFieldsValue({ jsonData: reader.result })
              } else {
                this.form.setFieldsValue({
                  jsonData: JSON.stringify(
                    JSON.parse(reader.result as string),
                    null,
                    4
                  ),
                })
              }
            }
          )
        }
      }
    }
  }

  /**
   * 清空文本框
   */
  public clearInputText() {
    this.form.setFieldsValue({ jsonData: '' })
    DataUploadStore.setHttpDatasetData(null)
    DataUploadStore.setDataInformationCollapsePanelShow(false) // 打开数据信息
  }

  /**
   * 执行
   */
  public importHttp(event: Event) {
    event.preventDefault()
    this.$nextTick(() => {
      this.form.validateFields(
        ['categoryId', 'datasetName', 'jsonData'],
        (error: any, values: any) => {
          if (!error) {
            const data = {
              datasetName: values.datasetName as string,
              jsonData: values.jsonData as string,
              result: this.lastResponse,
            }
            data.result.newHead = cloneDeep(data.result.head)
            data.result.fileName = data.datasetName
            const datasetData: any = data.result
            DataUploadStore.setHttpDatasetData(datasetData)
            DataUploadStore.setIsDataTypeInfer(true) // 使用类型推断
            DataUploadStore.setIsDataSemanticInfer(false) // 不使用语义推断
            DataUploadStore.setDataInformationCollapsePanelShow(true) // 打开数据信息
            // data upload success, user guide to the next step
            UserGuideStore.toSpecifiedGuideStep(4)
          }
        }
      )
    })
  }

  /**
   * 取消导入
   */
  public cancelImportData() {
    DataUploadStore.setHttpDatasetData(null)
  }

  /**
   * 确认导入
   */
  public handleSubmit() {
    this.form.validateFields(async (error: Error, values: any) => {
      if (!error) {
        const dataSend = {
          categoryId: values.categoryId, // 分类 id
          columnDTOList: this.httpDatasetData.newHead.map(
            (column: {
              name: string
              type: string
              semantic?: string
              recommendSemantic: string
            }) => {
              return {
                name: column.name,
                type: column.type,
                dataLevelId: null,
                dataMaskingType: null,
                importColumn: true,
                semantic: column.semantic ? column.semantic : 'null',
              }
            }
          ),
          data: Object.values(this.httpDatasetData.data[0]),
          importType: 'http',
          name: this.httpDatasetData.fileName,
        }
        // 保存http表信息，这里用回调方式方便监听错误信息
        HttpCreateTable({ data: dataSend }).then((response) => {
          if (response.data.code !== 100) {
            DataStore.setMessageModalOption({
              visible: true,
              message: '导入数据失败',
              tips: `原因：${response.data.message}\n提示：${response.data.tips}`,
            })
          }
          if (response.data.code === 100) {
            DataUploadStore.cancelImport()
            this.$message.success('操作成功！')
            const dataId: any = response.data.result
            this.goBackPreView('http', dataId)
            DataUploadStore.updateHttpDataSet()
              .then((result: any) => {
                if (result.data.code === 100) {
                  DataStore.setDatasetCategory(result.data.result) // 更新左侧数据集列表
                  DataStore.setSelectedDatasetId(dataId) // 左侧选择查看的数据集id
                  this.$emit('form-set-selected-keys', [`dataset${dataId}`])
                }
              })
              .catch(() => {
                this.$message.error('获取表信息失败，请刷新重试')
              })
            // data upload success, user guide to the next step
            UserGuideStore.toSpecifiedGuideStep(5)
          }
        })
      }
    })
  }
}
</script>
<style lang="less" scoped>
@import './data-type';

// http 类型
.select-http-type {
  height: 52px;
  margin-right: 16px;
  padding: 0;
  width: 80px;
}

.upload-file {
  // 文件上传 and 编辑
  .import-file-box {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin-bottom: 6px;

    // 文件上传
    .file-upload-button {
      // 文件上传提示
      .json-button-annotation {
        color: rgba(0, 0, 0, 0.45);
        font-size: 12px;
        font-weight: 400;
        letter-spacing: 1px;
        line-height: 17px;
        padding-left: 10px;
      }
    }

    // 清空 执行 button
    .json-edit-buttons {
      button {
        margin-left: 8px;
      }
    }
  }
}

.json-data {
  /deep/.ant-form-explain {
    padding-left: @FORM_LABEL_WIDTH;
  }
}
</style>
